package com.flashcash.solu.common.network;

import com.flashcash.solu.BuildConfig;
import com.flashcash.solu.app.App;
import com.flashcash.solu.common.EventCollection;
import com.flashcash.solu.common.TokenManager;
import com.flashcash.solu.harvester.uploadout.UploadUtils;
import com.google.gson.Gson;
import com.hwangjr.rxbus.RxBus;
import com.flashcash.kotlin.data.BasicAck;
import com.x.leo.apphelper.log.XLog;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Util;
import okhttp3.internal.http.HttpHeaders;
import okhttp3.internal.http.RealResponseBody;
import okio.GzipSource;
import okio.Okio;

/**
 * Created by XLEO on 2018/1/30.
 */

class DefaultHeaderAddInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request userRequest = chain.request();
        Request.Builder requestBuilder = userRequest.newBuilder();
        RequestBody body = userRequest.body();
        if (body != null) {
            MediaType contentType = body.contentType();
            if (contentType != null) {
                requestBuilder.header("Content-Type", contentType.toString());
            }

            long contentLength = body.contentLength();
            if (contentLength != -1L) {
                requestBuilder.header("Content-Length", Long.toString(contentLength));
                requestBuilder.removeHeader("Transfer-Encoding");
            } else {
                requestBuilder.header("Transfer-Encoding", "chunked");
                requestBuilder.removeHeader("Content-Length");
            }
        }

        if (userRequest.header("Host") == null) {
            requestBuilder.header("Host", Util.hostHeader(userRequest.url(), false));
        }

        if (userRequest.header("Connection") == null) {
            requestBuilder.header("Connection", "Keep-Alive");
        }

        boolean transparentGzip = false;
        if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) {
            transparentGzip = true;
            requestBuilder.header("Accept-Encoding", "gzip");
        }

        requestBuilder.header("X-APP-TYPE", "ANDROID")
                .header("X-APP-VERSION", String.valueOf(BuildConfig.VERSION_CODE))
                .header("X-APP-PACKAGE-NAME", getPackageName());

        Response networkResponse = chain.proceed(requestBuilder.build());
        networkResponse = handleResult(networkResponse, userRequest);
        okhttp3.Response.Builder responseBuilder = networkResponse.newBuilder().request(userRequest);
        if (transparentGzip && "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding")) && HttpHeaders.hasBody(networkResponse)) {
            GzipSource responseBody = new GzipSource(networkResponse.body().source());
            Headers strippedHeaders = networkResponse.headers().newBuilder().removeAll("Content-Encoding").removeAll("Content-Length").build();
            responseBuilder.headers(strippedHeaders);
            responseBuilder.body(new RealResponseBody(strippedHeaders, Okio.buffer(responseBody)));
        }

        return responseBuilder.build();
    }

    private @NotNull String getPackageName(){
        String name = "";
        try {
            name = App.instance.getPackageName();
        } catch (Exception e){
            UploadUtils.uploadException(e, "DefaultHeaderAddInterceptor.getPackageName");
        }
        return name;
    }

    private Response handleResult(Response response, Request userRequest) {
        if (response.code() == 401) {
//            response = handle401(chain, request, response);
            TokenManager.getInstance().refreshTokeExpired();
        }else if (response.code() == 403) {
            XLog.INSTANCE.i("403 interceptor:sms incorrect", 10);
            RxBus.get().post(new EventCollection.ErrorSMSCodeEvent());
        } else if (response.code() == 409) {
            try {
                XLog.INSTANCE.i("409 interceptor:version update needed", 10);
                Gson gson = new Gson();
                BasicAck result = gson.fromJson(response.body().string(), BasicAck.class);
                EventCollection.NeedUpdateEvent needUpdateEvent = gson.fromJson(result.getData(), EventCollection.NeedUpdateEvent.class);
                if (needUpdateEvent != null) {
                    RxBus.get().post(needUpdateEvent);
                }else {
                    EventCollection.NeedUpdateEvent event = new EventCollection.NeedUpdateEvent();
                    RxBus.get().post(event);
                }
                Response.Builder request = response.newBuilder().request(userRequest);
                request.code(200);
                request.body(ResponseBody.create(MediaType.parse("application/json"), "{}"));
                return request.build();
            } catch (Exception e) {
                XLog.INSTANCE.e("409 handle exception:" + e.getMessage(), e, 100);
                RxBus.get().post(new EventCollection.NeedUpdateEvent());
            }

        } else if (response.code() == 412) {
            XLog.INSTANCE.i("400 interceptor:params missing", 10);
            EventCollection.ParamsMissingEvent event = new EventCollection.ParamsMissingEvent();
            RxBus.get().post(event);
        }
        return response;

    }
}
